//! # RustCloud 通用测试工具模块
//!
//! 本模块提供了用于测试的通用Mock实现和工具函数，避免在各个模块中重复实现类似的测试代码。
//! 所有的Mock实现都遵循统一的接口，提供了一致的测试体验。
//!
//! ## 设计原则
//!
//! * **统一接口** - 所有Mock实现都基于相同的trait
//! * **可配置性** - 支持通过配置来模拟不同的行为
//! * **线程安全** - 所有Mock实现都是线程安全的
//! * **简单易用** - 提供简洁的API用于测试设置
//!
//! ## 使用示例
//!
//! ```rust
//! use rustcloud_test_utils::*;
//!
//! #[tokio::test]
//! async fn test_service_call() {
//!     let registry = MockRegistry::new();
//!     let load_balancer = MockLoadBalancer::new();
//!     let transport = MockTransport::new_with_response(200, b"OK");
//!     
//!     // 设置测试数据
//!     registry.add_instance("test-service", create_test_instance());
//!     
//!     // 执行测试
//!     let proxy = ServiceProxy::new(registry, load_balancer, transport, MockCircuitBreaker::new_always_closed());
//!     let response = proxy.call(create_test_request()).await.unwrap();
//!     
//!     assert_eq!(response.status, 200);
//! }
//! ```

use async_trait::async_trait;
use rustcloud_core::{
    ServiceInstance, ServiceRegistry, LoadBalancer, Transport, CircuitBreaker,
    Request, Response, ServiceResult, ServiceError, ServiceWatcher, ServiceRegistryEvent,
    CircuitBreakerState, CircuitBreakerMetrics, StrategyInfo, RequestContext
};
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::time::{Duration, SystemTime, Instant};
use tokio::sync::RwLock;

// =============================================================================
// Mock 服务注册中心
// =============================================================================

/// Mock服务注册中心
/// 
/// 提供内存中的服务实例存储，支持基本的注册发现功能。
/// 可以配置模拟失败场景。
pub struct MockRegistry {
    instances: Arc<RwLock<HashMap<String, Vec<ServiceInstance>>>>,
    should_fail: Arc<Mutex<bool>>,
    failure_rate: Arc<Mutex<f64>>,
}

impl MockRegistry {
    /// 创建新的Mock注册中心
    pub fn new() -> Self {
        Self {
            instances: Arc::new(RwLock::new(HashMap::new())),
            should_fail: Arc::new(Mutex::new(false)),
            failure_rate: Arc::new(Mutex::new(0.0)),
        }
    }

    /// 创建始终失败的Mock注册中心
    pub fn new_always_fail() -> Self {
        Self {
            instances: Arc::new(RwLock::new(HashMap::new())),
            should_fail: Arc::new(Mutex::new(true)),
            failure_rate: Arc::new(Mutex::new(1.0)),
        }
    }

    /// 设置失败率 (0.0 - 1.0)
    pub fn set_failure_rate(&self, rate: f64) {
        *self.failure_rate.lock().unwrap() = rate.clamp(0.0, 1.0);
    }

    /// 设置是否始终失败
    pub fn set_should_fail(&self, should_fail: bool) {
        *self.should_fail.lock().unwrap() = should_fail;
    }

    /// 添加服务实例
    pub async fn add_instance(&self, service_name: &str, instance: ServiceInstance) {
        let mut instances = self.instances.write().await;
        instances.entry(service_name.to_string()).or_insert_with(Vec::new).push(instance);
    }

    /// 移除服务实例
    pub async fn remove_instance(&self, service_name: &str, host: &str, port: u16) {
        let mut instances = self.instances.write().await;
        if let Some(service_instances) = instances.get_mut(service_name) {
            service_instances.retain(|i| !(i.host == host && i.port == port));
        }
    }

    /// 清空所有实例
    pub async fn clear_instances(&self) {
        self.instances.write().await.clear();
    }

    /// 获取实例数量
    pub async fn instance_count(&self, service_name: &str) -> usize {
        let instances = self.instances.read().await;
        instances.get(service_name).map(|v| v.len()).unwrap_or(0)
    }

    /// 模拟是否应该失败
    fn should_simulate_failure(&self) -> bool {
        if *self.should_fail.lock().unwrap() {
            return true;
        }
        
        let failure_rate = *self.failure_rate.lock().unwrap();
        if failure_rate <= 0.0 {
            return false;
        }
        
        use rand::Rng;
        let mut rng = rand::thread_rng();
        rng.gen::<f64>() < failure_rate
    }
}

#[async_trait]
impl ServiceRegistry for MockRegistry {
    async fn register(&self, instance: ServiceInstance) -> ServiceResult<()> {
        if self.should_simulate_failure() {
            return Err(ServiceError::RegistryError("Mock registration failure".to_string()));
        }
        
        self.add_instance(&instance.service_id, instance).await;
        Ok(())
    }

    async fn deregister(&self, instance: ServiceInstance) -> ServiceResult<()> {
        if self.should_simulate_failure() {
            return Err(ServiceError::RegistryError("Mock deregistration failure".to_string()));
        }
        
        self.remove_instance(&instance.service_id, &instance.host, instance.port).await;
        Ok(())
    }

    async fn discover(&self, service_name: &str) -> ServiceResult<Vec<ServiceInstance>> {
        if self.should_simulate_failure() {
            return Err(ServiceError::RegistryError("Mock discovery failure".to_string()));
        }
        
        let instances = self.instances.read().await;
        Ok(instances.get(service_name).cloned().unwrap_or_default())
    }

    async fn health_check(&self, service_name: &str) -> ServiceResult<Vec<ServiceInstance>> {
        if self.should_simulate_failure() {
            return Err(ServiceError::RegistryError("Mock health check failure".to_string()));
        }
        
        let instances = self.discover(service_name).await?;
        Ok(instances.into_iter().filter(|i| i.healthy).collect())
    }

    async fn watch(&self, _service_name: &str) -> ServiceResult<Box<dyn ServiceWatcher + Send>> {
        Ok(Box::new(MockServiceWatcher::new()))
    }
}

/// Mock服务监听器
pub struct MockServiceWatcher {
    events: Arc<Mutex<Vec<ServiceRegistryEvent>>>,
    current_index: Arc<Mutex<usize>>,
}

impl MockServiceWatcher {
    pub fn new() -> Self {
        Self {
            events: Arc::new(Mutex::new(Vec::new())),
            current_index: Arc::new(Mutex::new(0)),
        }
    }

    pub fn add_event(&self, event: ServiceRegistryEvent) {
        self.events.lock().unwrap().push(event);
    }
}

#[async_trait]
impl ServiceWatcher for MockServiceWatcher {
    async fn next_event(&mut self) -> ServiceResult<ServiceRegistryEvent> {
        let events = self.events.lock().unwrap();
        let mut index = self.current_index.lock().unwrap();
        
        if *index < events.len() {
            let event = events[*index].clone();
            *index += 1;
            Ok(event)
        } else {
            // 模拟等待新事件
            tokio::time::sleep(Duration::from_millis(100)).await;
            Err(ServiceError::Timeout("No more events".to_string()))
        }
    }
}

// =============================================================================
// Mock 负载均衡器
// =============================================================================

/// Mock负载均衡器
/// 
/// 支持多种选择策略，可以配置选择行为。
pub struct MockLoadBalancer {
    strategy: Arc<Mutex<LoadBalancerMockStrategy>>,
    call_count: Arc<Mutex<usize>>,
}

#[derive(Clone)]
pub enum LoadBalancerMockStrategy {
    /// 轮询选择
    RoundRobin,
    /// 始终选择第一个
    AlwaysFirst,
    /// 始终选择最后一个
    AlwaysLast,
    /// 随机选择
    Random,
    /// 始终返回空
    AlwaysEmpty,
}

impl MockLoadBalancer {
    /// 创建新的Mock负载均衡器（默认轮询）
    pub fn new() -> Self {
        Self {
            strategy: Arc::new(Mutex::new(LoadBalancerMockStrategy::RoundRobin)),
            call_count: Arc::new(Mutex::new(0)),
        }
    }

    /// 创建始终选择第一个实例的负载均衡器
    pub fn new_always_first() -> Self {
        Self {
            strategy: Arc::new(Mutex::new(LoadBalancerMockStrategy::AlwaysFirst)),
            call_count: Arc::new(Mutex::new(0)),
        }
    }

    /// 创建始终返回空的负载均衡器
    pub fn new_always_empty() -> Self {
        Self {
            strategy: Arc::new(Mutex::new(LoadBalancerMockStrategy::AlwaysEmpty)),
            call_count: Arc::new(Mutex::new(0)),
        }
    }

    /// 设置选择策略
    pub fn set_strategy(&self, strategy: LoadBalancerMockStrategy) {
        *self.strategy.lock().unwrap() = strategy;
    }

    /// 获取调用次数
    pub fn call_count(&self) -> usize {
        *self.call_count.lock().unwrap()
    }

    /// 重置调用次数
    pub fn reset_call_count(&self) {
        *self.call_count.lock().unwrap() = 0;
    }
}

#[async_trait]
impl LoadBalancer for MockLoadBalancer {
    async fn select(&self, _service_name: &str, instances: &[ServiceInstance]) -> ServiceResult<Option<ServiceInstance>> {
        let mut count = self.call_count.lock().unwrap();
        *count += 1;
        
        if instances.is_empty() {
            return Ok(None);
        }

        let strategy = self.strategy.lock().unwrap().clone();
        let selected = match strategy {
            LoadBalancerMockStrategy::RoundRobin => {
                let index = (*count - 1) % instances.len();
                instances.get(index).cloned()
            },
            LoadBalancerMockStrategy::AlwaysFirst => instances.first().cloned(),
            LoadBalancerMockStrategy::AlwaysLast => instances.last().cloned(),
            LoadBalancerMockStrategy::Random => {
                use rand::Rng;
                let mut rng = rand::thread_rng();
                let index = rng.gen_range(0..instances.len());
                instances.get(index).cloned()
            },
            LoadBalancerMockStrategy::AlwaysEmpty => None,
        };

        Ok(selected)
    }

    async fn select_with_context(&self, service_name: &str, instances: &[ServiceInstance], _context: &RequestContext) -> ServiceResult<Option<ServiceInstance>> {
        self.select(service_name, instances).await
    }

    fn name(&self) -> &str {
        "mock-load-balancer"
    }

    fn get_strategy_info(&self) -> StrategyInfo {
        StrategyInfo {
            name: "Mock Load Balancer".to_string(),
            description: "Mock implementation for testing".to_string(),
            requires_session_affinity: false,
            supports_weighted_routing: false,
        }
    }
}

// =============================================================================
// Mock 传输层
// =============================================================================

/// Mock传输层
/// 
/// 可以预设响应内容，支持模拟各种网络状况。
pub struct MockTransport {
    responses: Arc<Mutex<HashMap<String, Response>>>,
    default_response: Arc<Mutex<Option<Response>>>,
    call_count: Arc<Mutex<usize>>,
    should_fail: Arc<Mutex<bool>>,
    delay: Arc<Mutex<Option<Duration>>>,
}

impl MockTransport {
    /// 创建新的Mock传输层
    pub fn new() -> Self {
        Self {
            responses: Arc::new(Mutex::new(HashMap::new())),
            default_response: Arc::new(Mutex::new(None)),
            call_count: Arc::new(Mutex::new(0)),
            should_fail: Arc::new(Mutex::new(false)),
            delay: Arc::new(Mutex::new(None)),
        }
    }

    /// 创建带默认响应的Mock传输层
    pub fn new_with_response(status: u16, body: &[u8]) -> Self {
        let transport = Self::new();
        let mut response = Response::new(status);
        response.set_body(body.to_vec());
        transport.set_default_response(response);
        transport
    }

    /// 创建始终失败的Mock传输层
    pub fn new_always_fail() -> Self {
        let transport = Self::new();
        transport.set_should_fail(true);
        transport
    }

    /// 设置特定路径的响应
    pub fn set_response(&self, path: &str, response: Response) {
        self.responses.lock().unwrap().insert(path.to_string(), response);
    }

    /// 设置默认响应
    pub fn set_default_response(&self, response: Response) {
        *self.default_response.lock().unwrap() = Some(response);
    }

    /// 设置是否应该失败
    pub fn set_should_fail(&self, should_fail: bool) {
        *self.should_fail.lock().unwrap() = should_fail;
    }

    /// 设置请求延迟
    pub fn set_delay(&self, delay: Duration) {
        *self.delay.lock().unwrap() = Some(delay);
    }

    /// 获取调用次数
    pub fn call_count(&self) -> usize {
        *self.call_count.lock().unwrap()
    }

    /// 重置调用次数
    pub fn reset_call_count(&self) {
        *self.call_count.lock().unwrap() = 0;
    }
}

#[async_trait]
impl Transport for MockTransport {
    async fn send(&self, request: Request, _instance: &ServiceInstance) -> ServiceResult<Response> {
        // 模拟延迟
        if let Some(delay) = *self.delay.lock().unwrap() {
            tokio::time::sleep(delay).await;
        }

        // 增加调用计数
        *self.call_count.lock().unwrap() += 1;

        // 检查是否应该失败
        if *self.should_fail.lock().unwrap() {
            return Err(ServiceError::NetworkError("Mock transport failure".to_string()));
        }

        // 查找对应的响应
        let responses = self.responses.lock().unwrap();
        if let Some(response) = responses.get(&request.path) {
            return Ok(response.clone());
        }

        // 使用默认响应
        if let Some(response) = &*self.default_response.lock().unwrap() {
            return Ok(response.clone());
        }

        // 返回默认成功响应
        Ok(Response::new(200))
    }

    fn name(&self) -> &str {
        "mock-transport"
    }
}

// =============================================================================
// Mock 熔断器
// =============================================================================

/// Mock熔断器
/// 
/// 可以模拟不同的熔断状态，支持配置熔断行为。
pub struct MockCircuitBreaker {
    state: Arc<Mutex<CircuitBreakerState>>,
    should_break: Arc<Mutex<bool>>,
    call_count: Arc<Mutex<usize>>,
    success_count: Arc<Mutex<usize>>,
    failure_count: Arc<Mutex<usize>>,
}

impl MockCircuitBreaker {
    /// 创建新的Mock熔断器（默认关闭状态）
    pub fn new() -> Self {
        Self {
            state: Arc::new(Mutex::new(CircuitBreakerState::Closed)),
            should_break: Arc::new(Mutex::new(false)),
            call_count: Arc::new(Mutex::new(0)),
            success_count: Arc::new(Mutex::new(0)),
            failure_count: Arc::new(Mutex::new(0)),
        }
    }

    /// 创建始终关闭的Mock熔断器
    pub fn new_always_closed() -> Self {
        let cb = Self::new();
        cb.set_state(CircuitBreakerState::Closed);
        cb
    }

    /// 创建始终开启的Mock熔断器
    pub fn new_always_open() -> Self {
        let cb = Self::new();
        cb.set_state(CircuitBreakerState::Open);
        cb.set_should_break(true);
        cb
    }

    /// 设置熔断器状态
    pub fn set_state(&self, state: CircuitBreakerState) {
        *self.state.lock().unwrap() = state;
    }

    /// 设置是否应该熔断
    pub fn set_should_break(&self, should_break: bool) {
        *self.should_break.lock().unwrap() = should_break;
    }

    /// 获取调用次数
    pub fn call_count(&self) -> usize {
        *self.call_count.lock().unwrap()
    }

    /// 获取成功次数
    pub fn success_count(&self) -> usize {
        *self.success_count.lock().unwrap()
    }

    /// 获取失败次数
    pub fn failure_count(&self) -> usize {
        *self.failure_count.lock().unwrap()
    }

    /// 重置统计
    pub fn reset_stats(&self) {
        *self.call_count.lock().unwrap() = 0;
        *self.success_count.lock().unwrap() = 0;
        *self.failure_count.lock().unwrap() = 0;
    }
}

#[async_trait]
impl CircuitBreaker for MockCircuitBreaker {
    async fn call<F, Fut, T>(&self, _service_name: &str, operation: F) -> ServiceResult<T>
    where
        F: FnOnce() -> Fut + Send,
        Fut: std::future::Future<Output = ServiceResult<T>> + Send,
        T: Send,
    {
        *self.call_count.lock().unwrap() += 1;

        // 检查是否应该熔断
        if *self.should_break.lock().unwrap() || matches!(*self.state.lock().unwrap(), CircuitBreakerState::Open) {
            *self.failure_count.lock().unwrap() += 1;
            return Err(ServiceError::CircuitBreakerOpen("Circuit breaker is open".to_string()));
        }

        // 执行操作
        let result = operation().await;
        
        match &result {
            Ok(_) => *self.success_count.lock().unwrap() += 1,
            Err(_) => *self.failure_count.lock().unwrap() += 1,
        }

        result
    }

    async fn get_state(&self) -> CircuitBreakerState {
        *self.state.lock().unwrap()
    }

    async fn get_metrics(&self) -> CircuitBreakerMetrics {
        CircuitBreakerMetrics {
            total_requests: *self.call_count.lock().unwrap() as u64,
            successful_requests: *self.success_count.lock().unwrap() as u64,
            failed_requests: *self.failure_count.lock().unwrap() as u64,
            state: *self.state.lock().unwrap(),
            failure_rate: if *self.call_count.lock().unwrap() > 0 {
                *self.failure_count.lock().unwrap() as f64 / *self.call_count.lock().unwrap() as f64
            } else {
                0.0
            },
            last_failure_time: None,
            next_attempt_time: None,
        }
    }

    fn name(&self) -> &str {
        "mock-circuit-breaker"
    }
}

// =============================================================================
// 测试工具函数
// =============================================================================

/// 创建测试用的服务实例
pub fn create_test_instance() -> ServiceInstance {
    create_test_instance_with_name("test-service")
}

/// 创建指定名称的测试服务实例
pub fn create_test_instance_with_name(service_name: &str) -> ServiceInstance {
    ServiceInstance::new(service_name, "127.0.0.1", 8080, "http")
}

/// 创建测试用的服务实例（带端口）
pub fn create_test_instance_with_port(service_name: &str, port: u16) -> ServiceInstance {
    ServiceInstance::new(service_name, "127.0.0.1", port, "http")
}

/// 创建测试用的HTTP请求
pub fn create_test_request() -> Request {
    Request::new("test-service", "GET", "/api/test")
}

/// 创建指定方法和路径的测试请求
pub fn create_test_request_with_path(method: &str, path: &str) -> Request {
    Request::new("test-service", method, path)
}

/// 创建带请求体的测试请求
pub fn create_test_request_with_body(method: &str, path: &str, body: &[u8]) -> Request {
    let mut request = Request::new("test-service", method, path);
    request.set_body(body.to_vec());
    request
}

/// 创建测试用的HTTP响应
pub fn create_test_response(status: u16) -> Response {
    Response::new(status)
}

/// 创建带响应体的测试响应
pub fn create_test_response_with_body(status: u16, body: &[u8]) -> Response {
    let mut response = Response::new(status);
    response.set_body(body.to_vec());
    response
}

/// 创建测试环境
/// 
/// 返回一套完整的Mock组件，用于快速搭建测试环境。
pub fn create_test_environment() -> (Arc<MockRegistry>, Arc<MockLoadBalancer>, Arc<MockTransport>, Arc<MockCircuitBreaker>) {
    let registry = Arc::new(MockRegistry::new());
    let load_balancer = Arc::new(MockLoadBalancer::new());
    let transport = Arc::new(MockTransport::new());
    let circuit_breaker = Arc::new(MockCircuitBreaker::new());
    
    (registry, load_balancer, transport, circuit_breaker)
}

/// 创建预设成功的测试环境
/// 
/// 所有组件都配置为成功模式，适用于正常流程测试。
pub fn create_success_test_environment() -> (Arc<MockRegistry>, Arc<MockLoadBalancer>, Arc<MockTransport>, Arc<MockCircuitBreaker>) {
    let registry = Arc::new(MockRegistry::new());
    let load_balancer = Arc::new(MockLoadBalancer::new_always_first());
    let transport = Arc::new(MockTransport::new_with_response(200, b"OK"));
    let circuit_breaker = Arc::new(MockCircuitBreaker::new_always_closed());
    
    (registry, load_balancer, transport, circuit_breaker)
}

/// 创建预设失败的测试环境
/// 
/// 所有组件都配置为失败模式，适用于错误处理测试。
pub fn create_failure_test_environment() -> (Arc<MockRegistry>, Arc<MockLoadBalancer>, Arc<MockTransport>, Arc<MockCircuitBreaker>) {
    let registry = Arc::new(MockRegistry::new_always_fail());
    let load_balancer = Arc::new(MockLoadBalancer::new_always_empty());
    let transport = Arc::new(MockTransport::new_always_fail());
    let circuit_breaker = Arc::new(MockCircuitBreaker::new_always_open());
    
    (registry, load_balancer, transport, circuit_breaker)
}

// =============================================================================
// 测试用例辅助函数
// =============================================================================

/// 断言服务实例相等
pub fn assert_instance_eq(actual: &ServiceInstance, expected: &ServiceInstance) {
    assert_eq!(actual.service_id, expected.service_id);
    assert_eq!(actual.host, expected.host);
    assert_eq!(actual.port, expected.port);
    assert_eq!(actual.scheme, expected.scheme);
}

/// 断言响应状态码
pub fn assert_response_status(response: &Response, expected_status: u16) {
    assert_eq!(response.status, expected_status, "Response status mismatch");
}

/// 断言响应体内容
pub fn assert_response_body(response: &Response, expected_body: &[u8]) {
    match &response.body {
        Some(body) => assert_eq!(body, expected_body, "Response body mismatch"),
        None => panic!("Response body is None, expected: {:?}", expected_body),
    }
}

/// 等待条件满足（用于异步测试）
pub async fn wait_for_condition<F>(mut condition: F, timeout: Duration) -> bool
where
    F: FnMut() -> bool,
{
    let start = Instant::now();
    while start.elapsed() < timeout {
        if condition() {
            return true;
        }
        tokio::time::sleep(Duration::from_millis(10)).await;
    }
    false
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_mock_registry() {
        let registry = MockRegistry::new();
        let instance = create_test_instance();
        
        // 测试注册
        registry.register(instance.clone()).await.unwrap();
        
        // 测试发现
        let discovered = registry.discover("test-service").await.unwrap();
        assert_eq!(discovered.len(), 1);
        assert_instance_eq(&discovered[0], &instance);
    }
    
    #[tokio::test]
    async fn test_mock_load_balancer() {
        let lb = MockLoadBalancer::new();
        let instances = vec![
            create_test_instance_with_port("service", 8080),
            create_test_instance_with_port("service", 8081),
        ];
        
        // 测试轮询选择
        let selected1 = lb.select("service", &instances).await.unwrap().unwrap();
        let selected2 = lb.select("service", &instances).await.unwrap().unwrap();
        
        assert_eq!(selected1.port, 8080);
        assert_eq!(selected2.port, 8081);
        assert_eq!(lb.call_count(), 2);
    }
    
    #[tokio::test]
    async fn test_mock_transport() {
        let transport = MockTransport::new_with_response(200, b"Hello");
        let request = create_test_request();
        let instance = create_test_instance();
        
        let response = transport.send(request, &instance).await.unwrap();
        assert_response_status(&response, 200);
        assert_response_body(&response, b"Hello");
        assert_eq!(transport.call_count(), 1);
    }
    
    #[tokio::test]
    async fn test_mock_circuit_breaker() {
        let cb = MockCircuitBreaker::new_always_closed();
        
        // 测试成功调用
        let result = cb.call("test", || async { Ok::<i32, ServiceError>(42) }).await;
        assert!(result.is_ok());
        assert_eq!(result.unwrap(), 42);
        assert_eq!(cb.success_count(), 1);
        
        // 测试失败调用
        let result = cb.call("test", || async { Err::<i32, ServiceError>(ServiceError::NetworkError("test".to_string())) }).await;
        assert!(result.is_err());
        assert_eq!(cb.failure_count(), 1);
    }
    
    #[test]
    fn test_test_environment() {
        let (registry, lb, transport, cb) = create_test_environment();
        assert_eq!(registry.call_count, Arc::strong_count(&registry.call_count));
        assert_eq!(lb.call_count(), 0);
        assert_eq!(transport.call_count(), 0);
        assert_eq!(cb.call_count(), 0);
    }
}